@jbrowse/core 5.0.0-beta.1 → 5.0.0-beta.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +112 -43
- package/esm/BaseFeatureWidget/BaseFeatureDetail/FeatureDetails.d.ts +2 -3
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.d.ts +4 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/ParentFeatureLine.js +17 -0
- package/esm/BaseFeatureWidget/BaseFeatureDetail/index.js +4 -3
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/SequenceFeaturePanel.d.ts +2 -2
- package/esm/BaseFeatureWidget/SequenceFeatureDetails/test_data/NCDN.d.ts +2 -2
- package/esm/BaseFeatureWidget/index.d.ts +1 -1
- package/esm/BaseFeatureWidget/stateModelFactory.d.ts +8 -1
- package/esm/BaseFeatureWidget/stateModelFactory.js +6 -0
- package/esm/BaseFeatureWidget/types.d.ts +10 -2
- package/esm/PluginLoader.d.ts +1 -0
- package/esm/PluginLoader.js +52 -8
- package/esm/PluginManager.d.ts +99 -17
- package/esm/PluginManager.js +194 -26
- package/esm/ReExports/BaseFeatureDetails.js +1 -1
- package/esm/ReExports/MuiDataGridReExports.d.ts +1 -0
- package/esm/ReExports/MuiDataGridReExports.js +2 -2
- package/esm/ReExports/barrelOnlyNames.d.ts +5 -0
- package/esm/ReExports/barrelOnlyNames.js +63 -0
- package/esm/ReExports/modules.js +31 -109
- package/esm/ReExports/publicTracks.d.ts +1 -0
- package/esm/ReExports/publicTracks.js +14 -0
- package/esm/ReExports/publicUi.d.ts +4 -0
- package/esm/ReExports/publicUi.js +33 -0
- package/esm/ReExports/publicUtil.d.ts +1 -1
- package/esm/ReExports/publicUtil.js +8 -4
- package/esm/ReExports/sharedModules.d.ts +96 -0
- package/esm/ReExports/sharedModules.js +66 -0
- package/esm/ReExports/uiStub.d.ts +2 -0
- package/esm/ReExports/uiStub.js +11 -0
- package/esm/ReExports/workerModules.d.ts +2 -0
- package/esm/ReExports/workerModules.js +15 -0
- package/esm/ReExports/workerNamespaceNames.d.ts +11 -0
- package/esm/ReExports/workerNamespaceNames.js +281 -0
- package/esm/configuration/configurationSchema.d.ts +5 -38
- package/esm/configuration/configurationSchema.js +64 -40
- package/esm/configuration/index.d.ts +2 -2
- package/esm/configuration/index.js +1 -1
- package/esm/configuration/promotableDefaults.d.ts +54 -19
- package/esm/configuration/promotableDefaults.js +117 -48
- package/esm/configuration/promotablePin.d.ts +50 -40
- package/esm/configuration/promotableResolve.d.ts +1 -1
- package/esm/configuration/promotableResolve.js +1 -1
- package/esm/configuration/tabixIndexFields.d.ts +2 -2
- package/esm/configuration/tabixIndexFields.js +2 -2
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.d.ts +12 -0
- package/esm/data_adapters/BaseAdapter/BaseFeatureDataAdapter.js +35 -4
- package/esm/data_adapters/BaseAdapter/featureDensity.d.ts +41 -0
- package/esm/data_adapters/BaseAdapter/featureDensity.js +32 -0
- package/esm/data_adapters/BaseAdapter/index.d.ts +2 -1
- package/esm/data_adapters/BaseAdapter/index.js +1 -0
- package/esm/data_adapters/BaseAdapter/stats.d.ts +33 -1
- package/esm/data_adapters/BaseAdapter/stats.js +52 -13
- package/esm/data_adapters/BaseAdapter/types.d.ts +3 -8
- package/esm/pluggableElementTypes/AdapterType.d.ts +2 -1
- package/esm/pluggableElementTypes/AdapterType.js +1 -1
- package/esm/pluggableElementTypes/DisplayType.d.ts +4 -12
- package/esm/pluggableElementTypes/DisplayType.js +3 -10
- package/esm/pluggableElementTypes/LazyStateModelElement.d.ts +27 -0
- package/esm/pluggableElementTypes/LazyStateModelElement.js +71 -0
- package/esm/pluggableElementTypes/ViewType.d.ts +20 -4
- package/esm/pluggableElementTypes/ViewType.js +32 -4
- package/esm/pluggableElementTypes/extendElementType.d.ts +1 -2
- package/esm/pluggableElementTypes/extendElementType.js +9 -5
- package/esm/pluggableElementTypes/models/BaseDisplayModel.d.ts +44 -3
- package/esm/pluggableElementTypes/models/BaseDisplayModel.js +75 -2
- package/esm/pluggableElementTypes/models/BaseTrackModel.d.ts +21 -0
- package/esm/pluggableElementTypes/models/BaseTrackModel.js +34 -2
- package/esm/pluggableElementTypes/models/BaseViewModel.d.ts +49 -0
- package/esm/pluggableElementTypes/models/BaseViewModel.js +28 -0
- package/esm/pluggableElementTypes/models/assertDisplayContract.d.ts +14 -10
- package/esm/pluggableElementTypes/models/assertDisplayContract.js +25 -32
- package/esm/pluggableElementTypes/models/baseTrackConfig.js +7 -1
- package/esm/rpc/RpcRegistry.d.ts +10 -0
- package/esm/rpc/byteBudget.d.ts +9 -0
- package/esm/rpc/coreRpcMethods.d.ts +1 -0
- package/esm/rpc/coreRpcMethods.js +1 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.d.ts +11 -0
- package/esm/rpc/methods/CoreGetFeatureDensity.js +22 -0
- package/esm/svg/svgReady.d.ts +1 -0
- package/esm/ui/BaseExportSvgDialog.d.ts +1 -1
- package/esm/ui/CascadingMenu.js +30 -8
- package/esm/ui/ErrorMessageStackTraceDialog.js +5 -6
- package/esm/ui/ExportSvgDialog.d.ts +1 -1
- package/esm/ui/LoadingOverlay.d.ts +14 -0
- package/esm/ui/LoadingOverlay.js +1 -1
- package/esm/ui/MenuTypes.d.ts +14 -5
- package/esm/ui/MenuTypes.js +3 -0
- package/esm/ui/PaletteContext.d.ts +11 -4
- package/esm/ui/PaletteContext.js +34 -5
- package/esm/ui/PinAdornment.js +31 -43
- package/esm/ui/ScrollChrome.d.ts +16 -0
- package/esm/ui/ScrollChrome.js +12 -0
- package/esm/ui/ScrollZoomToggle.d.ts +4 -3
- package/esm/ui/ScrollZoomToggle.js +4 -3
- package/esm/ui/SizeSliderRow.js +1 -1
- package/esm/ui/index.d.ts +3 -3
- package/esm/ui/index.js +4 -4
- package/esm/ui/launchViewMenu.js +7 -1
- package/esm/ui/legendMenuItem.d.ts +10 -16
- package/esm/ui/legendMenuItem.js +9 -20
- package/esm/ui/makeSizeMenu.js +1 -1
- package/esm/ui/menuItemAdornment.d.ts +2 -3
- package/esm/ui/menuItemAdornment.js +2 -3
- package/esm/ui/menuItems.d.ts +2 -3
- package/esm/ui/menuItems.js +1 -2
- package/esm/ui/palette.d.ts +11 -11
- package/esm/ui/palette.js +11 -11
- package/esm/ui/promotablePinCoverage.d.ts +16 -2
- package/esm/ui/promotablePinCoverage.js +40 -3
- package/esm/ui/theme.js +5 -0
- package/esm/ui/toggleMenuItems.d.ts +14 -9
- package/esm/ui/toggleMenuItems.js +32 -15
- package/esm/util/Base1DUtils.d.ts +4 -2
- package/esm/util/Base1DUtils.js +12 -4
- package/esm/util/SvgCanvas.js +4 -3
- package/esm/util/adapterConfigKey.d.ts +12 -0
- package/esm/util/adapterConfigKey.js +14 -0
- package/esm/util/adapterMetadata.js +2 -1
- package/esm/util/addAndShowTrack.d.ts +1 -1
- package/esm/util/addAndShowTrack.js +5 -1
- package/esm/util/addTrackFromWidget.js +2 -2
- package/esm/util/analytics.js +4 -5
- package/esm/util/cacheBudgets.d.ts +22 -19
- package/esm/util/cacheBudgets.js +22 -19
- package/esm/util/clampToContig.d.ts +17 -0
- package/esm/util/clampToContig.js +19 -0
- package/esm/util/colorBits.d.ts +2 -1
- package/esm/util/colorBits.js +2 -5
- package/esm/util/createStopTokenRotation.d.ts +9 -7
- package/esm/util/createStopTokenRotation.js +7 -27
- package/esm/util/featureTypes.d.ts +24 -0
- package/esm/util/featureTypes.js +35 -0
- package/esm/util/fetchContext.d.ts +2 -2
- package/esm/util/fetchContext.js +2 -2
- package/esm/util/fetchPhases.d.ts +10 -10
- package/esm/util/hooks.d.ts +8 -0
- package/esm/util/hooks.js +27 -0
- package/esm/util/index.d.ts +6 -5
- package/esm/util/index.js +5 -4
- package/esm/util/installFetch.d.ts +71 -34
- package/esm/util/installFetch.js +57 -29
- package/esm/util/installInitAutorun.d.ts +14 -13
- package/esm/util/installInitAutorun.js +17 -17
- package/esm/util/installPrerequisiteFetch.d.ts +86 -0
- package/esm/util/installPrerequisiteFetch.js +73 -0
- package/esm/util/lazyAfterAttach.d.ts +13 -0
- package/esm/util/lazyAfterAttach.js +31 -0
- package/esm/util/legendCandidates.d.ts +50 -0
- package/esm/util/legendCandidates.js +87 -0
- package/esm/util/mstUtils.d.ts +12 -1
- package/esm/util/mstUtils.js +20 -2
- package/esm/util/openFeatureWidget.d.ts +5 -0
- package/esm/util/openFeatureWidget.js +1 -0
- package/esm/util/openViews.d.ts +16 -0
- package/esm/util/openViews.js +22 -0
- package/esm/util/parentWalk.d.ts +1 -1
- package/esm/util/parentWalk.js +1 -1
- package/esm/util/pluginStore.d.ts +1 -0
- package/esm/util/pluginStore.js +8 -1
- package/esm/util/range.d.ts +13 -9
- package/esm/util/range.js +17 -8
- package/esm/util/renderToStaticMarkup.js +10 -0
- package/esm/util/rxjs.d.ts +16 -0
- package/esm/util/rxjs.js +49 -0
- package/esm/util/scheduleDetachedDestroy.d.ts +18 -0
- package/esm/util/scheduleDetachedDestroy.js +24 -0
- package/esm/util/scrollLatch.d.ts +1 -0
- package/esm/util/scrollLatch.js +8 -0
- package/esm/util/stopToken.d.ts +6 -5
- package/esm/util/tabix.d.ts +10 -4
- package/esm/util/tabix.js +11 -5
- package/esm/util/trackConfigDelta.d.ts +6 -6
- package/esm/util/trackConfigDelta.js +3 -3
- package/esm/util/tracks.d.ts +48 -0
- package/esm/util/tracks.js +192 -66
- package/esm/util/types/index.d.ts +58 -10
- package/esm/util/types/index.js +3 -0
- package/esm/util/unknownSnapshotKeys.d.ts +36 -0
- package/esm/util/unknownSnapshotKeys.js +69 -0
- package/esm/util/usePanelVirtualScroll.d.ts +6 -2
- package/esm/util/usePanelVirtualScroll.js +6 -2
- package/esm/util/useRowVirtualScroll.d.ts +1 -1
- package/esm/util/useRowVirtualScroll.js +1 -1
- package/esm/util/useVirtualScrollWheel.js +11 -1
- package/esm/util/viewStatus.d.ts +23 -0
- package/esm/util/viewStatus.js +17 -0
- package/esm/util/wheelZoom.d.ts +3 -1
- package/esm/util/wheelZoom.js +39 -14
- package/esm/util/whenViewSettled.d.ts +17 -4
- package/esm/util/whenViewSettled.js +19 -6
- package/esm/util/withLaunchInput.d.ts +168 -0
- package/esm/util/withLaunchInput.js +273 -0
- package/package.json +19 -11
- package/esm/ui/promotableMenuItems.d.ts +0 -19
- package/esm/ui/promotableMenuItems.js +0 -89
- package/esm/util/applyInitSettings.d.ts +0 -79
- package/esm/util/applyInitSettings.js +0 -91
package/esm/util/mstUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type PluginManager from '../PluginManager.ts';
|
|
2
|
-
import type { AbstractDisplayModel, AbstractSessionModel, AbstractTrackModel, AbstractViewModel } from './types/index.ts';
|
|
2
|
+
import type { AbstractDisplayModel, AbstractSessionModel, AbstractViewContainer, AbstractTrackModel, AbstractViewModel } from './types/index.ts';
|
|
3
3
|
import type { AssemblyHost, RenderingServices } from './types/renderingServices.ts';
|
|
4
4
|
import type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
5
5
|
export { findParentThat, findParentThatIs, getRpcSessionId, } from './parentWalk.ts';
|
|
@@ -85,5 +85,16 @@ export declare function canonicalizeViewRefName(node: IAnyStateTreeNode, refName
|
|
|
85
85
|
export declare function getEnv(obj: IAnyStateTreeNode): {
|
|
86
86
|
pluginManager: PluginManager;
|
|
87
87
|
};
|
|
88
|
+
/**
|
|
89
|
+
* #api core/util
|
|
90
|
+
* `addOrReplaceView` for view types whose state model may be lazily loaded;
|
|
91
|
+
* the synchronous `addOrReplaceView` requires it loaded already.
|
|
92
|
+
*/
|
|
93
|
+
export declare function launchOrReplaceView(args: {
|
|
94
|
+
session: AbstractViewContainer;
|
|
95
|
+
typeName: string;
|
|
96
|
+
initialState?: Record<string, unknown>;
|
|
97
|
+
replacing?: AbstractViewModel;
|
|
98
|
+
}): Promise<AbstractViewModel>;
|
|
88
99
|
export declare function hashCode(str: string): number;
|
|
89
100
|
export declare function objectHash(obj: object): string;
|
package/esm/util/mstUtils.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { getEnv as getEnvMST } from '@jbrowse/mobx-state-tree';
|
|
1
|
+
import { getEnv as getEnvMST, isStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
2
|
import { cachedParent, findParentThatIs } from './parentWalk.js';
|
|
3
|
-
import { isDisplayModel, isSessionModel, isTrackModel, isViewModel, } from './types/index.js';
|
|
3
|
+
import { addOrReplaceView, isDisplayModel, isSessionModel, isTrackModel, isViewModel, } from './types/index.js';
|
|
4
4
|
export { findParentThat, findParentThatIs, getRpcSessionId, } from './parentWalk.js';
|
|
5
5
|
const containingDisplayCache = new WeakMap();
|
|
6
6
|
const containingTrackCache = new WeakMap();
|
|
@@ -105,6 +105,24 @@ export function canonicalizeViewRefName(node, refName) {
|
|
|
105
105
|
export function getEnv(obj) {
|
|
106
106
|
return getEnvMST(obj);
|
|
107
107
|
}
|
|
108
|
+
/**
|
|
109
|
+
* #api core/util
|
|
110
|
+
* `addOrReplaceView` for view types whose state model may be lazily loaded;
|
|
111
|
+
* the synchronous `addOrReplaceView` requires it loaded already.
|
|
112
|
+
*/
|
|
113
|
+
export async function launchOrReplaceView(args) {
|
|
114
|
+
// a test's fake session is not an MST node; addView's own guard is the
|
|
115
|
+
// error path there
|
|
116
|
+
if (isStateTreeNode(args.session)) {
|
|
117
|
+
const { pluginManager } = getEnvMST(args.session);
|
|
118
|
+
await pluginManager?.getViewType(args.typeName).loadStateModel();
|
|
119
|
+
// the displays of the tracks a launch opens with are dynamic imports too
|
|
120
|
+
await pluginManager?.preloadSessionTypes({
|
|
121
|
+
views: [{ type: args.typeName, ...args.initialState }],
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
return addOrReplaceView(args);
|
|
125
|
+
}
|
|
108
126
|
export function hashCode(str) {
|
|
109
127
|
let hash = 0;
|
|
110
128
|
if (str.length === 0) {
|
|
@@ -5,10 +5,15 @@ export interface FeatureWidgetTypeRef {
|
|
|
5
5
|
type: string;
|
|
6
6
|
id: string;
|
|
7
7
|
}
|
|
8
|
+
export interface ParentFeatureSummary {
|
|
9
|
+
name: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
}
|
|
8
12
|
export declare function openFeatureWidget(node: IAnyStateTreeNode, featureData: SimpleFeatureSerialized, opts?: {
|
|
9
13
|
widget?: FeatureWidgetTypeRef;
|
|
10
14
|
extra?: Record<string, unknown>;
|
|
11
15
|
feature?: Feature;
|
|
16
|
+
parentFeature?: ParentFeatureSummary;
|
|
12
17
|
}): Widget | undefined;
|
|
13
18
|
/**
|
|
14
19
|
* The other half of the flow above: the details lookup came back with nothing,
|
|
@@ -32,6 +32,7 @@ export function openFeatureWidget(node, featureData, opts = {}) {
|
|
|
32
32
|
const { type, id } = opts.widget ?? DEFAULT_FEATURE_WIDGET;
|
|
33
33
|
const widget = session.addWidget(type, id, {
|
|
34
34
|
featureData,
|
|
35
|
+
parentFeature: opts.parentFeature,
|
|
35
36
|
view: getContainingView(node),
|
|
36
37
|
track: getContainingTrack(node),
|
|
37
38
|
...opts.extra,
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { AbstractSessionModel, AbstractTrackModel, AbstractViewModel } from './types/index.ts';
|
|
2
|
+
/**
|
|
3
|
+
* "What is open" — the reduction four consumers wanted and each used to walk
|
|
4
|
+
* for itself (AppReadyMarker, jbApi, and capture's session gate and busy
|
|
5
|
+
* check), on different and drifting spellings of the view nesting.
|
|
6
|
+
*
|
|
7
|
+
* The recursion lives here, once. What each view contributes lives on the view,
|
|
8
|
+
* once, as `ownViews`/`ownTracks`. Neither half guesses at the other: the
|
|
9
|
+
* census is declared intent, not a shape that can be discovered, because the
|
|
10
|
+
* two things that look enumerable are not — the dotplot's `views` prop holds
|
|
11
|
+
* view-shaped axis models the user never opened, and react-msaview's `tracks`
|
|
12
|
+
* getter holds annotation rows that are not tracks.
|
|
13
|
+
*/
|
|
14
|
+
export declare function openViews(session: AbstractSessionModel): AbstractViewModel[];
|
|
15
|
+
/** Every track on every open view. */
|
|
16
|
+
export declare function openTracks(session: AbstractSessionModel): AbstractTrackModel[];
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* "What is open" — the reduction four consumers wanted and each used to walk
|
|
3
|
+
* for itself (AppReadyMarker, jbApi, and capture's session gate and busy
|
|
4
|
+
* check), on different and drifting spellings of the view nesting.
|
|
5
|
+
*
|
|
6
|
+
* The recursion lives here, once. What each view contributes lives on the view,
|
|
7
|
+
* once, as `ownViews`/`ownTracks`. Neither half guesses at the other: the
|
|
8
|
+
* census is declared intent, not a shape that can be discovered, because the
|
|
9
|
+
* two things that look enumerable are not — the dotplot's `views` prop holds
|
|
10
|
+
* view-shaped axis models the user never opened, and react-msaview's `tracks`
|
|
11
|
+
* getter holds annotation rows that are not tracks.
|
|
12
|
+
*/
|
|
13
|
+
export function openViews(session) {
|
|
14
|
+
return session.views.flatMap(withNested);
|
|
15
|
+
}
|
|
16
|
+
/** Every track on every open view. */
|
|
17
|
+
export function openTracks(session) {
|
|
18
|
+
return openViews(session).flatMap(v => v.ownTracks ?? []);
|
|
19
|
+
}
|
|
20
|
+
function withNested(view) {
|
|
21
|
+
return [view, ...(view.ownViews ?? []).flatMap(withNested)];
|
|
22
|
+
}
|
package/esm/util/parentWalk.d.ts
CHANGED
|
@@ -14,7 +14,7 @@ export declare function findParentThatIs<T extends (a: IAnyStateTreeNode) => boo
|
|
|
14
14
|
* Keying on the node is safe because nothing re-parents one — both `detach`
|
|
15
15
|
* call sites hand the node straight to `scheduleDetachedDestroy` (ADR-069), so
|
|
16
16
|
* a cached ancestor can only go stale by dying, which the `isAlive` check
|
|
17
|
-
* catches. That is the difference from the three memos
|
|
17
|
+
* catches. That is the difference from the three memos agent-docs/architecture-decision-records/ records
|
|
18
18
|
* removing: each keyed on something its caller had just allocated.
|
|
19
19
|
*/
|
|
20
20
|
export declare function cachedParent<T>(cache: WeakMap<IAnyStateTreeNode, T>, node: IAnyStateTreeNode, finder: () => T, errorMsg: string): T;
|
package/esm/util/parentWalk.js
CHANGED
|
@@ -39,7 +39,7 @@ export function findParentThatIs(node, predicate) {
|
|
|
39
39
|
* Keying on the node is safe because nothing re-parents one — both `detach`
|
|
40
40
|
* call sites hand the node straight to `scheduleDetachedDestroy` (ADR-069), so
|
|
41
41
|
* a cached ancestor can only go stale by dying, which the `isAlive` check
|
|
42
|
-
* catches. That is the difference from the three memos
|
|
42
|
+
* catches. That is the difference from the three memos agent-docs/architecture-decision-records/ records
|
|
43
43
|
* removing: each keyed on something its caller had just allocated.
|
|
44
44
|
*/
|
|
45
45
|
export function cachedParent(cache, node, finder, errorMsg) {
|
|
@@ -34,6 +34,7 @@ export interface PluginUpdate {
|
|
|
34
34
|
name: string;
|
|
35
35
|
definition: PluginDefinition;
|
|
36
36
|
}
|
|
37
|
+
export declare function releaseVersion(jbrowseVersion: string): string;
|
|
37
38
|
export declare function resolvePlugin(plugin: JBrowsePlugin, jbrowseVersion: string): ResolvedPlugin;
|
|
38
39
|
export declare function installedVersionFromUrl(url: string | undefined, packageName: string | undefined): string | undefined;
|
|
39
40
|
/**
|
package/esm/util/pluginStore.js
CHANGED
|
@@ -37,6 +37,13 @@ export function installablePlugins(plugins, isElectron) {
|
|
|
37
37
|
(isElectron ||
|
|
38
38
|
publishedBuilds(plugin).some(b => b.esmUrl ?? b.url ?? b.umdUrl)));
|
|
39
39
|
}
|
|
40
|
+
// A prerelease host is its release for compatibility purposes. Under semver
|
|
41
|
+
// 5.0.0-beta.1 sorts below 5.0.0, so a range written to keep a plugin off v5
|
|
42
|
+
// (`<5.0.0`) would serve it to every beta host and a v5-only range (`>=5.0.0`)
|
|
43
|
+
// would hide it from them. Store ranges are written against release versions.
|
|
44
|
+
export function releaseVersion(jbrowseVersion) {
|
|
45
|
+
return jbrowseVersion.split('-')[0];
|
|
46
|
+
}
|
|
40
47
|
// `*` (and empty) mean "any JBrowse version"; compare-versions throws on those,
|
|
41
48
|
// so handle them directly. A malformed range simply fails to match rather than
|
|
42
49
|
// breaking the store UI — producer-side validation is the place to reject those.
|
|
@@ -44,7 +51,7 @@ function rangeMatches(jbrowseVersion, range) {
|
|
|
44
51
|
let matched = range === '*' || range === '';
|
|
45
52
|
if (!matched) {
|
|
46
53
|
try {
|
|
47
|
-
matched = satisfies(jbrowseVersion, range);
|
|
54
|
+
matched = satisfies(releaseVersion(jbrowseVersion), range);
|
|
48
55
|
}
|
|
49
56
|
catch {
|
|
50
57
|
matched = false;
|
package/esm/util/range.d.ts
CHANGED
|
@@ -20,9 +20,15 @@ export declare function doesIntersect2(left1: number, right1: number, left2: num
|
|
|
20
20
|
/**
|
|
21
21
|
* Compute the expanded fetch range a tabix adapter must "redispatch" to when
|
|
22
22
|
* features found in a query extend past the requested window. Returns the union
|
|
23
|
-
* of the query with the bounds of every
|
|
24
|
-
*
|
|
25
|
-
*
|
|
23
|
+
* of the query with the bounds of every line `expands` admits, or `undefined`
|
|
24
|
+
* when nothing extends past the query (no redispatch needed).
|
|
25
|
+
*
|
|
26
|
+
* **A predicate, not a set of types**, because the useful question is not what a
|
|
27
|
+
* record is called. The bound exists to reach a record's *children*, so what
|
|
28
|
+
* disqualifies a record is having none — and in GFF3 that is answerable exactly,
|
|
29
|
+
* from whether the record carries an `ID` for a `Parent` to reference. A type
|
|
30
|
+
* blocklist can only ever approximate it, and it is the caller's format that
|
|
31
|
+
* knows how: this file reads no column but the coordinates.
|
|
26
32
|
*
|
|
27
33
|
* Feature coordinates arrive interbase, matching the query: @gmod/tabix applies
|
|
28
34
|
* the index's coordinate offset before invoking the line callback, so a GFF/GTF
|
|
@@ -30,15 +36,13 @@ export declare function doesIntersect2(left1: number, right1: number, left2: num
|
|
|
30
36
|
*
|
|
31
37
|
* Seeding the accumulator with the query bounds is what makes the result a
|
|
32
38
|
* union rather than just the feature bounds. A redispatch narrower than the
|
|
33
|
-
* original window would drop
|
|
34
|
-
*
|
|
35
|
-
* those types are deliberately excluded from the bounds.
|
|
39
|
+
* original window would drop an excluded line that the first fetch found inside
|
|
40
|
+
* the query but that falls outside the expanded range.
|
|
36
41
|
*/
|
|
37
|
-
export declare function calculateRedispatchRange
|
|
42
|
+
export declare function calculateRedispatchRange<T extends {
|
|
38
43
|
start: number;
|
|
39
44
|
end: number;
|
|
40
|
-
|
|
41
|
-
}[], dontRedispatchSet: Set<string>, queryStart: number, queryEnd: number): {
|
|
45
|
+
}>(features: T[], expands: (feature: T) => boolean, queryStart: number, queryEnd: number): {
|
|
42
46
|
start: number;
|
|
43
47
|
end: number;
|
|
44
48
|
} | undefined;
|
package/esm/util/range.js
CHANGED
|
@@ -45,9 +45,15 @@ export function doesIntersect2(left1, right1, left2, right2) {
|
|
|
45
45
|
/**
|
|
46
46
|
* Compute the expanded fetch range a tabix adapter must "redispatch" to when
|
|
47
47
|
* features found in a query extend past the requested window. Returns the union
|
|
48
|
-
* of the query with the bounds of every
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* of the query with the bounds of every line `expands` admits, or `undefined`
|
|
49
|
+
* when nothing extends past the query (no redispatch needed).
|
|
50
|
+
*
|
|
51
|
+
* **A predicate, not a set of types**, because the useful question is not what a
|
|
52
|
+
* record is called. The bound exists to reach a record's *children*, so what
|
|
53
|
+
* disqualifies a record is having none — and in GFF3 that is answerable exactly,
|
|
54
|
+
* from whether the record carries an `ID` for a `Parent` to reference. A type
|
|
55
|
+
* blocklist can only ever approximate it, and it is the caller's format that
|
|
56
|
+
* knows how: this file reads no column but the coordinates.
|
|
51
57
|
*
|
|
52
58
|
* Feature coordinates arrive interbase, matching the query: @gmod/tabix applies
|
|
53
59
|
* the index's coordinate offset before invoking the line callback, so a GFF/GTF
|
|
@@ -55,15 +61,18 @@ export function doesIntersect2(left1, right1, left2, right2) {
|
|
|
55
61
|
*
|
|
56
62
|
* Seeding the accumulator with the query bounds is what makes the result a
|
|
57
63
|
* union rather than just the feature bounds. A redispatch narrower than the
|
|
58
|
-
* original window would drop
|
|
59
|
-
*
|
|
60
|
-
* those types are deliberately excluded from the bounds.
|
|
64
|
+
* original window would drop an excluded line that the first fetch found inside
|
|
65
|
+
* the query but that falls outside the expanded range.
|
|
61
66
|
*/
|
|
62
|
-
export function calculateRedispatchRange(features,
|
|
67
|
+
export function calculateRedispatchRange(features, expands, queryStart, queryEnd) {
|
|
63
68
|
let minStart = queryStart;
|
|
64
69
|
let maxEnd = queryEnd;
|
|
70
|
+
// bounds first: only a line reaching past the current bound can widen it, so
|
|
71
|
+
// the predicate, which may scan the line's text, runs on those few lines and
|
|
72
|
+
// not on every line in the window
|
|
65
73
|
for (const feature of features) {
|
|
66
|
-
if (
|
|
74
|
+
if ((feature.start < minStart || feature.end > maxEnd) &&
|
|
75
|
+
expands(feature)) {
|
|
67
76
|
if (feature.start < minStart) {
|
|
68
77
|
minStart = feature.start;
|
|
69
78
|
}
|
|
@@ -7,6 +7,16 @@ import { createRoot } from 'react-dom/client';
|
|
|
7
7
|
// reason to pull react/react-dom/@emotion, and the barrel is imported by
|
|
8
8
|
// worker-side adapter code that never renders.
|
|
9
9
|
//
|
|
10
|
+
// It is not part of the plugin ABI either, and that removal did break two
|
|
11
|
+
// published bundles before anyone noticed: react-msaview's SVG export read it
|
|
12
|
+
// off `@jbrowse/core/util`, and jbrowse-plugin-msaview and -tview bundle
|
|
13
|
+
// react-msaview. Resolved on their side -- react-msaview owns its own copy now
|
|
14
|
+
// (packages/lib/src/renderToStaticMarkup.ts there) -- because a rendering
|
|
15
|
+
// library asking its host for a renderer was the coupling worth removing, and
|
|
16
|
+
// because react-dom is a host external for a plugin anyway, so it costs them a
|
|
17
|
+
// few hundred bytes rather than a duplicate react. sharedModules.purity.test.ts
|
|
18
|
+
// is what keeps this file off the worker's graph now.
|
|
19
|
+
//
|
|
10
20
|
// https://react.dev/reference/react-dom/server/renderToString#removing-rendertostring-from-the-client-code
|
|
11
21
|
export function renderToStaticMarkup(node) {
|
|
12
22
|
const div = document.createElement('div');
|
package/esm/util/rxjs.d.ts
CHANGED
|
@@ -15,3 +15,19 @@ import type { Observer } from 'rxjs';
|
|
|
15
15
|
* @param func - observer function, could be async
|
|
16
16
|
*/
|
|
17
17
|
export declare function ObservableCreate<T>(func: (arg: Observer<T>) => void | Promise<void>, stopToken?: StopToken): Observable<T>;
|
|
18
|
+
/**
|
|
19
|
+
* Subscribe to an observable and resolve when it completes, running `onNext` per
|
|
20
|
+
* item as it arrives — the streaming shape for parsing items out of a feature
|
|
21
|
+
* stream rather than collecting them first.
|
|
22
|
+
*
|
|
23
|
+
* **`onNext` throwing rejects the promise.** rxjs does not do that on its own:
|
|
24
|
+
* an exception out of a `next` handler goes to its global unhandled-error hook,
|
|
25
|
+
* so the subscriber keeps being fed and `complete` still fires — a bare promise
|
|
26
|
+
* around that resolves as *success* with the items silently missing. Beside
|
|
27
|
+
* `ObservableCreate` because it is the other half of the pattern: the adapter
|
|
28
|
+
* wraps its body in that, the RPC `await`s this, so a per-item parse failure
|
|
29
|
+
* surfaces as a track error instead of a blank-but-loaded track.
|
|
30
|
+
*
|
|
31
|
+
* The source is unsubscribed on the first throw.
|
|
32
|
+
*/
|
|
33
|
+
export declare function subscribeToObservable<T>(observable: Observable<T>, onNext: (item: T) => void): Promise<void>;
|
package/esm/util/rxjs.js
CHANGED
|
@@ -43,3 +43,52 @@ export function ObservableCreate(func, stopToken) {
|
|
|
43
43
|
};
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Subscribe to an observable and resolve when it completes, running `onNext` per
|
|
48
|
+
* item as it arrives — the streaming shape for parsing items out of a feature
|
|
49
|
+
* stream rather than collecting them first.
|
|
50
|
+
*
|
|
51
|
+
* **`onNext` throwing rejects the promise.** rxjs does not do that on its own:
|
|
52
|
+
* an exception out of a `next` handler goes to its global unhandled-error hook,
|
|
53
|
+
* so the subscriber keeps being fed and `complete` still fires — a bare promise
|
|
54
|
+
* around that resolves as *success* with the items silently missing. Beside
|
|
55
|
+
* `ObservableCreate` because it is the other half of the pattern: the adapter
|
|
56
|
+
* wraps its body in that, the RPC `await`s this, so a per-item parse failure
|
|
57
|
+
* surfaces as a track error instead of a blank-but-loaded track.
|
|
58
|
+
*
|
|
59
|
+
* The source is unsubscribed on the first throw.
|
|
60
|
+
*/
|
|
61
|
+
export function subscribeToObservable(observable, onNext) {
|
|
62
|
+
return new Promise((resolve, reject) => {
|
|
63
|
+
// A box rather than two bare `let`s: oxlint narrows a flag assigned only
|
|
64
|
+
// inside a closure to its initializer and reports the reads as always-false.
|
|
65
|
+
// `subscription` is genuinely still undefined during a synchronous source's
|
|
66
|
+
// first emissions, which is why it is read optionally below.
|
|
67
|
+
const state = {
|
|
68
|
+
failed: false,
|
|
69
|
+
};
|
|
70
|
+
state.subscription = observable.subscribe({
|
|
71
|
+
next: item => {
|
|
72
|
+
if (!state.failed) {
|
|
73
|
+
try {
|
|
74
|
+
onNext(item);
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
state.failed = true;
|
|
78
|
+
// A parser throws an Error in every real case here; the wrap is for
|
|
79
|
+
// the rule that a rejection reason must be one, and keeps whatever
|
|
80
|
+
// was actually thrown as the `cause`.
|
|
81
|
+
reject(e instanceof Error ? e : new Error(String(e), { cause: e }));
|
|
82
|
+
state.subscription?.unsubscribe();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
},
|
|
86
|
+
error: reject,
|
|
87
|
+
complete: () => {
|
|
88
|
+
if (!state.failed) {
|
|
89
|
+
resolve();
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { IAnyStateTreeNode } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* Free a tree an action has already let go of — a superseded session, a view
|
|
4
|
+
* taken out of one, a superseded rootModel the React host has detached.
|
|
5
|
+
*
|
|
6
|
+
* A task rather than a microtask: the wait is for React to unmount the
|
|
7
|
+
* components rendering it, which happens on the re-render that the action's own
|
|
8
|
+
* reactions schedule. Deferring is acceptable here, and is not elsewhere,
|
|
9
|
+
* because the node stays alive and detached until it fires — a late read gets a
|
|
10
|
+
* live tree nobody is rendering. ADR-069.
|
|
11
|
+
*
|
|
12
|
+
* The destroy itself is not optional. `beforeDestroy` is a plugin-facing
|
|
13
|
+
* contract (jbrowse-plugin-apollo aborts its in-flight fetches there) and core's
|
|
14
|
+
* `BaseTrackModel` releases the `rpcSessionId` claim that lets
|
|
15
|
+
* `CoreFreeResources` evict a parsed adapter from the worker — so detaching and
|
|
16
|
+
* forgetting would trade a console warning for an unbounded leak.
|
|
17
|
+
*/
|
|
18
|
+
export declare function scheduleDetachedDestroy(node: IAnyStateTreeNode): void;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { destroy, isAlive } from '@jbrowse/mobx-state-tree';
|
|
2
|
+
/**
|
|
3
|
+
* Free a tree an action has already let go of — a superseded session, a view
|
|
4
|
+
* taken out of one, a superseded rootModel the React host has detached.
|
|
5
|
+
*
|
|
6
|
+
* A task rather than a microtask: the wait is for React to unmount the
|
|
7
|
+
* components rendering it, which happens on the re-render that the action's own
|
|
8
|
+
* reactions schedule. Deferring is acceptable here, and is not elsewhere,
|
|
9
|
+
* because the node stays alive and detached until it fires — a late read gets a
|
|
10
|
+
* live tree nobody is rendering. ADR-069.
|
|
11
|
+
*
|
|
12
|
+
* The destroy itself is not optional. `beforeDestroy` is a plugin-facing
|
|
13
|
+
* contract (jbrowse-plugin-apollo aborts its in-flight fetches there) and core's
|
|
14
|
+
* `BaseTrackModel` releases the `rpcSessionId` claim that lets
|
|
15
|
+
* `CoreFreeResources` evict a parsed adapter from the worker — so detaching and
|
|
16
|
+
* forgetting would trade a console warning for an unbounded leak.
|
|
17
|
+
*/
|
|
18
|
+
export function scheduleDetachedDestroy(node) {
|
|
19
|
+
setTimeout(() => {
|
|
20
|
+
if (isAlive(node)) {
|
|
21
|
+
destroy(node);
|
|
22
|
+
}
|
|
23
|
+
}, 0);
|
|
24
|
+
}
|
package/esm/util/scrollLatch.js
CHANGED
|
@@ -47,6 +47,14 @@ export function createScrollLatch(timeoutMs = LATCH_TIMEOUT_MS) {
|
|
|
47
47
|
}
|
|
48
48
|
return null;
|
|
49
49
|
},
|
|
50
|
+
// Whether this panel already owns the gesture `e` belongs to, i.e. it has
|
|
51
|
+
// scrolled during a run of events this one continues. Callers ask before
|
|
52
|
+
// declining an event on their own rules: a gesture that has latched keeps
|
|
53
|
+
// every event it fires, cross-axis momentum included, which is the whole
|
|
54
|
+
// point of latching.
|
|
55
|
+
holds(e) {
|
|
56
|
+
return latched && e.timeStamp - lastEvent < timeoutMs;
|
|
57
|
+
},
|
|
50
58
|
// Forget the gesture state so the next event is treated as a fresh gesture.
|
|
51
59
|
// Called when the pointer leaves the panel: a gesture the browser has
|
|
52
60
|
// latched to this element must not keep the page suppressed once the cursor
|
package/esm/util/stopToken.d.ts
CHANGED
|
@@ -31,11 +31,12 @@ import type { TimeGate } from './timeGate.ts';
|
|
|
31
31
|
* either way over a 2000x BAM cancel burst) and that measurement was sound but
|
|
32
32
|
* scoped: every loop on the alignments path is already chunked by awaits at
|
|
33
33
|
* region granularity, so there was nothing there for an intra-loop probe to
|
|
34
|
-
* interrupt. The counter-example is
|
|
35
|
-
* millions of
|
|
36
|
-
* only thing that can stop the work, and
|
|
37
|
-
* future attempt to delete this needs a
|
|
38
|
-
* await-free workload
|
|
34
|
+
* interrupt. The counter-example is the multi-sample-variant genotype matrix
|
|
35
|
+
* fill (`VariantRPC/getGenotypeMatrix.ts`) — millions of cells with no await
|
|
36
|
+
* anywhere, where this probe is the only thing that can stop the work, and
|
|
37
|
+
* which that bench never exercises. Any future attempt to delete this needs a
|
|
38
|
+
* cancel measurement on an await-free workload, not on a pileup. LD's O(n²)
|
|
39
|
+
* pair fill was the original example and went with the in-browser estimator.
|
|
39
40
|
*
|
|
40
41
|
* ## Which path runs where
|
|
41
42
|
*
|
package/esm/util/tabix.d.ts
CHANGED
|
@@ -45,9 +45,15 @@ export declare function readTabixLines(gff: TabixLineSource, refName: string, st
|
|
|
45
45
|
* Read a region's tabix lines, then — if any feature found there extends past
|
|
46
46
|
* the query — read the overhang on either side, so a parent line's children (a
|
|
47
47
|
* gene's exons, a transcript's CDS) outside the original window are pulled in
|
|
48
|
-
* and the parent/child tree resolves fully.
|
|
49
|
-
*
|
|
50
|
-
*
|
|
48
|
+
* and the parent/child tree resolves fully. `expands` decides which lines widen
|
|
49
|
+
* the bound, so one chromosome-spanning record can't force a whole-chromosome
|
|
50
|
+
* refetch; {@link calculateRedispatchRange} says why that is a predicate.
|
|
51
|
+
*
|
|
52
|
+
* **There is one control, and skipping the expansion is a value of it**: an
|
|
53
|
+
* `expands` that admits nothing reads the query and stops. A caller that wants
|
|
54
|
+
* that says so to its adapter, which is the layer that knows whether its format
|
|
55
|
+
* can honour it — see `Gff3TabixAdapter`, and `GtfTabixAdapter` for a format
|
|
56
|
+
* that cannot.
|
|
51
57
|
*
|
|
52
58
|
* **The flanks, not the union.** Re-reading `[minStart, maxEnd]` returns
|
|
53
59
|
* everything the first read already had — a second full read of the query range
|
|
@@ -76,7 +82,7 @@ export declare function readTabixLinesRedispatched(file: TabixLineSource, query:
|
|
|
76
82
|
refName: string;
|
|
77
83
|
start: number;
|
|
78
84
|
end: number;
|
|
79
|
-
},
|
|
85
|
+
}, expands: (line: TabixLine) => boolean, opts?: {
|
|
80
86
|
statusCallback?: StatusCallback;
|
|
81
87
|
stopToken?: StopToken;
|
|
82
88
|
}): Promise<TabixLine[]>;
|
package/esm/util/tabix.js
CHANGED
|
@@ -44,9 +44,15 @@ export function readTabixLines(gff, refName, start, end, statusCallback, stopTok
|
|
|
44
44
|
* Read a region's tabix lines, then — if any feature found there extends past
|
|
45
45
|
* the query — read the overhang on either side, so a parent line's children (a
|
|
46
46
|
* gene's exons, a transcript's CDS) outside the original window are pulled in
|
|
47
|
-
* and the parent/child tree resolves fully.
|
|
48
|
-
*
|
|
49
|
-
*
|
|
47
|
+
* and the parent/child tree resolves fully. `expands` decides which lines widen
|
|
48
|
+
* the bound, so one chromosome-spanning record can't force a whole-chromosome
|
|
49
|
+
* refetch; {@link calculateRedispatchRange} says why that is a predicate.
|
|
50
|
+
*
|
|
51
|
+
* **There is one control, and skipping the expansion is a value of it**: an
|
|
52
|
+
* `expands` that admits nothing reads the query and stops. A caller that wants
|
|
53
|
+
* that says so to its adapter, which is the layer that knows whether its format
|
|
54
|
+
* can honour it — see `Gff3TabixAdapter`, and `GtfTabixAdapter` for a format
|
|
55
|
+
* that cannot.
|
|
50
56
|
*
|
|
51
57
|
* **The flanks, not the union.** Re-reading `[minStart, maxEnd]` returns
|
|
52
58
|
* everything the first read already had — a second full read of the query range
|
|
@@ -74,13 +80,13 @@ export function readTabixLines(gff, refName, start, end, statusCallback, stopTok
|
|
|
74
80
|
export async function readTabixLinesRedispatched(file,
|
|
75
81
|
// the region's locus only — kept structural, like TabixLineSource above, so
|
|
76
82
|
// this module stays free of the `types` barrel and its MST models
|
|
77
|
-
query,
|
|
83
|
+
query, expands, opts = {}) {
|
|
78
84
|
const { statusCallback, stopToken } = opts;
|
|
79
85
|
// `cb` is not optional: each read decides where it reports, and the flanks
|
|
80
86
|
// report somewhere the first read does not
|
|
81
87
|
const read = (start, end, cb) => readTabixLines(file, query.refName, start, end, cb, stopToken);
|
|
82
88
|
const lines = await read(query.start, query.end, statusCallback);
|
|
83
|
-
const redispatch = calculateRedispatchRange(lines,
|
|
89
|
+
const redispatch = calculateRedispatchRange(lines, expands, query.start, query.end);
|
|
84
90
|
if (redispatch) {
|
|
85
91
|
const slot = createStatusFanOut(statusCallback);
|
|
86
92
|
const flanks = await Promise.all([
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
* empty delta, and `SessionTracks.updateTrackConfiguration` used to read that as
|
|
24
24
|
* "the edit netted back to the base" and revert the track's working copy — which
|
|
25
25
|
* undid a removal on screen 400ms after it landed. Promotable slots made that
|
|
26
|
-
* reachable rather than rare:
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* reachable rather than rare: a slider row's reset unsets its slot, and an
|
|
27
|
+
* admin config is free to set one. That branch now keeps the working copy; see
|
|
28
|
+
* the comment there.
|
|
29
29
|
*
|
|
30
30
|
* `displays` is merged by `displayId` so an edit to one display doesn't pin the
|
|
31
31
|
* others. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
|
@@ -59,9 +59,9 @@ export declare function mergeTrackConfig(base: Record<string, unknown>, delta: R
|
|
|
59
59
|
export interface TrackConfigChange {
|
|
60
60
|
/**
|
|
61
61
|
* Where the setting lives, and — for a row a UI can revert — its **address**:
|
|
62
|
-
* `
|
|
63
|
-
* into the type and slot it clears. So a producer that
|
|
64
|
-
* heading sets `label` and leaves this alone.
|
|
62
|
+
* product-core's `resetDisplayDefault` parses a promoted display-type
|
|
63
|
+
* default's path back into the type and slot it clears. So a producer that
|
|
64
|
+
* wants a friendlier heading sets `label` and leaves this alone.
|
|
65
65
|
*/
|
|
66
66
|
path: string[];
|
|
67
67
|
from: Json;
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
* empty delta, and `SessionTracks.updateTrackConfiguration` used to read that as
|
|
24
24
|
* "the edit netted back to the base" and revert the track's working copy — which
|
|
25
25
|
* undid a removal on screen 400ms after it landed. Promotable slots made that
|
|
26
|
-
* reachable rather than rare:
|
|
27
|
-
*
|
|
28
|
-
*
|
|
26
|
+
* reachable rather than rare: a slider row's reset unsets its slot, and an
|
|
27
|
+
* admin config is free to set one. That branch now keeps the working copy; see
|
|
28
|
+
* the comment there.
|
|
29
29
|
*
|
|
30
30
|
* `displays` is merged by `displayId` so an edit to one display doesn't pin the
|
|
31
31
|
* others. Nested config objects (e.g. `adapter`) recurse. Any other array (value
|
package/esm/util/tracks.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { getRpcSessionId } from './parentWalk.ts';
|
|
|
3
3
|
import type PluginManager from '../PluginManager.ts';
|
|
4
4
|
import type { AnyConfigurationModel } from '../configuration/index.ts';
|
|
5
5
|
import type { BlobLocation, FileHandleLocation, FileLocation, PreFileLocation } from './types/data.ts';
|
|
6
|
+
import type { AbstractViewContainer } from './types/index.ts';
|
|
6
7
|
import type { IAnyStateTreeNode, IAnyType, IStateTreeNode, Instance, types } from '@jbrowse/mobx-state-tree';
|
|
7
8
|
export declare function getTrackAssemblyNames(track: IStateTreeNode & {
|
|
8
9
|
configuration: AnyConfigurationModel;
|
|
@@ -242,6 +243,23 @@ export declare function guessTrackConf(input: string | LooseTrackInput, pluginMa
|
|
|
242
243
|
assemblyNames: string[];
|
|
243
244
|
adapter: AdapterConfig;
|
|
244
245
|
};
|
|
246
|
+
/**
|
|
247
|
+
* {@link guessTrackConf} over an already-built {@link FileLocation}, for a
|
|
248
|
+
* caller holding a location the loose `{ uri }` vocabulary cannot spell — a
|
|
249
|
+
* desktop local path. Kept separate so `LooseTrackInput` stays URI-only: it
|
|
250
|
+
* sits on the track-config union and the root config's `tracks`, where a
|
|
251
|
+
* local path would be a config a web deployment could not open.
|
|
252
|
+
*
|
|
253
|
+
* The `trackId` is a content hash of the adapter, not a timestamp, so adding
|
|
254
|
+
* the same file twice is idempotent — `addToSession` dedupes on it.
|
|
255
|
+
*/
|
|
256
|
+
export declare function guessTrackConfForLocation(file: FileLocation, index: FileLocation | undefined, pluginManager: PluginManager, assemblyName?: string): {
|
|
257
|
+
trackId: string;
|
|
258
|
+
type: string;
|
|
259
|
+
name: string;
|
|
260
|
+
assemblyNames: string[];
|
|
261
|
+
adapter: AdapterConfig;
|
|
262
|
+
};
|
|
245
263
|
/**
|
|
246
264
|
* Whether a track snapshot is the loose `{ uri, ... }` form — a data file with
|
|
247
265
|
* no `adapter` — that {@link expandLooseTrackConfig} expands.
|
|
@@ -294,6 +312,7 @@ interface MinimalTrack extends IAnyType {
|
|
|
294
312
|
interface GenericView {
|
|
295
313
|
type: string;
|
|
296
314
|
tracks: MSTArray<MinimalTrack>;
|
|
315
|
+
showTrack?: (trackId: string, initialSnapshot?: object, displayInitialSnapshot?: DisplayInitialSnapshot, inlineConf?: Record<string, unknown>) => unknown;
|
|
297
316
|
}
|
|
298
317
|
/**
|
|
299
318
|
* The display-snapshot argument of `showTrackGeneric`, exported so a view's own
|
|
@@ -403,6 +422,8 @@ export declare function stripTrackIds(tracks: TrackSnapshot[]): {
|
|
|
403
422
|
}[];
|
|
404
423
|
export declare function hideTrackGeneric(self: GenericView, trackId: string): boolean;
|
|
405
424
|
export declare function toggleTrackGeneric(self: GenericView, trackId: string): boolean;
|
|
425
|
+
export declare function launchTrackGeneric(self: GenericView, trackId: string, initialSnapshot?: object, displayInitialSnapshot?: DisplayInitialSnapshot, inlineConf?: Record<string, unknown>): Promise<any>;
|
|
426
|
+
export declare function launchToggleTrackGeneric(self: GenericView, trackId: string): Promise<boolean>;
|
|
406
427
|
/**
|
|
407
428
|
* Every track config the session can show, connection-supplied ones included.
|
|
408
429
|
*
|
|
@@ -424,3 +445,30 @@ export declare function allSessionTracks(session: {
|
|
|
424
445
|
setSubschema(slotName: string, data: Record<string, unknown>): any;
|
|
425
446
|
setSlot(slotName: string, value: unknown): void;
|
|
426
447
|
} & IStateTreeNode<import("../configuration/types.ts").AnyConfigurationSchemaType>)[];
|
|
448
|
+
/**
|
|
449
|
+
* The session's annotation for `assemblyName`, as trackIds: what a view opened
|
|
450
|
+
* on another genome starts with. Only FeatureTracks, not everything configured
|
|
451
|
+
* for the assembly — an alignments track turned on behind the user's back
|
|
452
|
+
* fetches data nobody asked for, and a FeatureTrack over a few kb is one tabix
|
|
453
|
+
* range query.
|
|
454
|
+
*/
|
|
455
|
+
export declare function annotationTrackIds(session: {
|
|
456
|
+
tracks: AnyConfigurationModel[];
|
|
457
|
+
connectionInstances?: {
|
|
458
|
+
tracks: AnyConfigurationModel[];
|
|
459
|
+
}[];
|
|
460
|
+
assemblyManager: AssemblyNameResolver;
|
|
461
|
+
}, assemblyName: string): string[];
|
|
462
|
+
/**
|
|
463
|
+
* One assembly on its own in a linear genome view, at `loc`. Keyed on `id`:
|
|
464
|
+
* following several alignments to one genome re-navigates the view rather than
|
|
465
|
+
* stacking a new one each time.
|
|
466
|
+
*/
|
|
467
|
+
export declare function openAssemblyInLinearView({ session, id, assemblyName, loc, tracks, }: {
|
|
468
|
+
session: AbstractViewContainer;
|
|
469
|
+
id: string;
|
|
470
|
+
assemblyName: string;
|
|
471
|
+
loc: string;
|
|
472
|
+
tracks: TrackInit[];
|
|
473
|
+
}): Promise<void>;
|
|
474
|
+
export declare function openMateLabel(assemblyName: string): string;
|